/*
 * 项目名称：DS18B20联网温度计
 * 功能描述：通过DS18B20温度传感器读取温度，并通过MQTT协议将温度数据发布到巴法云平台
 * 硬件配置：ESP8266 + DS18B20温度传感器（数据引脚GPIO13）
 * 作者：拿烙铁的赫
 * 日期：2025年7月4日
 */

#include <ESP8266WiFi.h>      // ESP8266 WiFi功能库
#include "PubSubClient.h"     // MQTT客户端库
#include <OneWire.h>          // 单总线协议库
#include <DallasTemperature.h> // DS18B20温度传感器库

// WiFi配置
const char* ssid = "CMCC-3DFC";      // 替换为你的WiFi名称，WiFi必须为2.4G的，不能使用5GWiFi
const char* password = "12345678";   // 替换为你的WiFi密码

// MQTT配置
const char* mqtt_server = "bemfa.com"; // MQTT服务器地址
const int mqtt_server_port = 9501;     // MQTT服务器端口
#define ID_MQTT  "*******************" // 替换为你的巴法云密钥
const char* topicG = "wenduji004";     // t替换为你的温度发布主题

WiFiClient espClient;                 // WiFi客户端对象
PubSubClient client(espClient);       // MQTT客户端对象

// 温度传感器配置
#define ONE_WIRE_BUS 13               // DS18B20数据引脚(GPIO13)
OneWire oneWire(ONE_WIRE_BUS);        // 单总线实例
DallasTemperature sensors(&oneWire);  // 温度传感器实例

// 函数声明
void setup_wifi();                    // 初始化WiFi连接
void reconnect();                     // MQTT重连函数

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("正在连接WiFi: ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);  // 启动WiFi连接

  // 等待WiFi连接成功
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi连接成功");
  Serial.print("IP地址: ");
  Serial.println(WiFi.localIP());  // 打印获取到的IP地址
}



// MQTT重连函数
void reconnect() {
  // 循环直到重新连接成功
  while (!client.connected()) {
    Serial.print("尝试MQTT连接...");
    
    // 尝试连接
    if (client.connect(ID_MQTT)) {
      Serial.println("MQTT连接成功");
      


    } else {
      Serial.print("连接失败, rc=");
      Serial.print(client.state());
      Serial.println(" 5秒后重试...");
      delay(5000);  // 等待5秒后重试
    }
  }
}

void setup() {
  Serial.begin(115200);        // 初始化串口通信
  
  setup_wifi();                // 连接WiFi
  
  // 配置MQTT客户端
  client.setServer(mqtt_server, mqtt_server_port);
  
  sensors.begin();             // 初始化温度传感器
  Serial.println("温度传感器初始化完成");
}

void loop() {
  // 保持MQTT连接
  if (!client.connected()) {
    reconnect();
  }
  client.loop();  // 处理MQTT消息

  // 温度读取与发布逻辑
  static unsigned long lastTempReadTime = 0; // 上次读取时间记录
  const long tempInterval = 1000;           // 温度读取间隔(1秒)
  
  if (millis() - lastTempReadTime >= tempInterval) {
    sensors.requestTemperatures();           // 请求温度读取
    
    // 获取传感器的摄氏温度值
    float temperature = sensors.getTempCByIndex(0);
    
    // 创建温度字符串（保留两位小数）
    char tempString[8];
    dtostrf(temperature, 6, 2, tempString);  // 格式转换
    
    // 发布温度数据到MQTT
    if (client.publish(topicG, tempString)) {
      Serial.print("温度发布成功: ");
      Serial.print(tempString);
      Serial.println("°C");
    } else {
      Serial.println("温度发布失败!");
    }
    
    lastTempReadTime = millis();  // 更新最后读取时间
  }
}